/*
 * Utility.cpp
 *
 *  Created on: 16-Feb-2013
 *      Author: abhijeet
 */

#include "Utility.h"

void WriteDisassemplyToFile(char const* filename) {
	int memLoc;
	string buffer;
	stringstream ss;
	ofstream out;
	out.open(filename);

	for (memLoc = STARTADDR; memLoc <= InstLimit; memLoc += 4) {
		Instruction *instruction;
		instruction = instructionMap.at(memLoc);

		instruction->GetInstruction(memLoc, 0, buffer);
		buffer += "\n";
		out << buffer;
		buffer.clear();
	}
	buffer.clear();

	for (; memLoc <= memoryLimit; memLoc += 4) {
		ss << memoryMap[memLoc] << "\t" << memLoc << "\t" << Memory[memLoc]
				<< "\n";
		out << ss.str();
		ss.str(std::string());
		ss.clear();
	}
	out.close();
}

void WriteSimulationToFile(int count, int _PC, char * filename) {
	string registerString;
	string memoryString;
	string instructionString;
	stringstream ss;
	Instruction *instruction;
	ofstream out;
	out.open(filename, ios::out | ios::app);

	instruction = instructionMap.at(_PC);
	instruction->GetInstruction(_PC, 1, instructionString);

	GetRegistersValues(registerString);
	GetMemoryValues(memoryString);

	ss << "--------------------\n";
	ss << "Cycle:" << count << "\t" << instructionString << "\n\n";
	ss << registerString;
	ss << memoryString;
	out << ss.str();
	out.close();

	ss.str(std::string());
	ss.clear();
}

int ValidateInputFile(char const* filename) {
	FILE *file;
	file = fopen(filename, "r");
	char *line = NULL;
	size_t len;
	int lineno = 1;

	if (file == NULL) {
		cerr << "Unable to open the input file: " << filename << endl;
		exit(1);
	}

	while (getline(&line, &len, file) != -1) {

		if (strlen(line) < 32 || strlen(line) > 35) {
			cerr << "Invalid instruction in file" << endl;
			cerr << "Line no: " << lineno << endl;
			exit(1);
		}

		line[32] = '\0';

		//Fix this code

		/*for (int i = 0; i <= 31; i++) {
			if (line[i] != '0' || line[i] != '1') {
				cout << '\n' << line[i] << endl;
				cerr << "2. Invalid instruction in file" << endl;
				cerr << "Line no: " << lineno << endl;
				exit(1);
			}*/

			//cout << line << endl;
			lineno++;
		}

	fclose(file);
	free(line);
}

void GetRegistersValues(string &buffer) {
	int j;
	stringstream ss;
//memoryLimit;
//InstLimit;

	ss << "Registers\nR00:";

	for (j = 0; j <= 7; j++) {
		ss << '\t' << Register[j];
	}
	ss << '\n' << "R08:";

	for (j = 8; j <= 15; j++) {
		ss << '\t' << Register[j];
	}

	ss << '\n' << "R16:";

	for (j = 16; j <= 23; j++) {
		ss << '\t' << Register[j];
	}

	ss << '\n' << "R24:";

	for (j = 24; j <= 31; j++) {
		ss << '\t' << Register[j];
	}
	ss << "\n\n";
	buffer += ss.str();
}

void GetMemoryValues(string &buffer) {
	int j;
	stringstream ss;

	ss << "Data\n";

	for(int rowNo=InstLimit+4; rowNo<=memoryLimit; rowNo += (8*4)){
		ss << rowNo << ":\t" ;
		for(int j=0;j<=28 && j<=memoryLimit ; j+=4){
			if ( j!=28)
				ss << Memory[rowNo+j] << '\t' ;
			else
				ss << Memory[rowNo+j];
		}
		ss << '\n';
	}
	buffer += ss.str();
	buffer += "\n";
}
